package com.linkgie.galaxyframework.web;

import java.io.IOException;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.linkgie.galaxyframework.utils.Pagination;
import com.linkgie.galaxyframework.utils.RuntimeIOException;
import com.linkgie.galaxyframework.utils.RuntimeStatus;
import com.linkgie.galaxyframework.utils.json.JsonSerialize;

/**
 * Web 服务的回复类型 ServiceResponse 的 JSON 序列化器；
 */
@SuppressWarnings("rawtypes")
public class ServiceResponseSerializer implements JsonSerialize<ServiceResponse> {

    @Override
    public void serialize(ServiceResponse responseObject, JsonGenerator gen, SerializerProvider serializers) {
        ObjectMapper mapper = (ObjectMapper) gen.getCodec();
        try {
            gen.writeStartObject();

            // 成功标识；
            gen.writeBooleanField("success", responseObject.isSuccess());
            // 状态码；
            gen.writeNumberField("code", responseObject.getCode());
            // 状态；
            RuntimeStatus status = responseObject.getStatus();
            if (status != null) {
                gen.writeObjectField("status", status);
            }
            // 描述信息;
            String message = responseObject.getMessage();
            if (message != null) {
                gen.writeStringField("message", message);
            }
            // 分页；
            Pagination pagination = responseObject.getPagination();
            if (pagination != null) {
                gen.writeObjectField("pagination", pagination);
                writeField("pagination", pagination, Pagination.class, gen, mapper);
            }
            // 重定向属性；
            String redirectTo = responseObject.getRedirectTo();
            if (redirectTo != null) {
                gen.writeStringField("redirectTo", redirectTo);
            }

            Object data = responseObject.getData();
            Class<?> dataType = responseObject.getDataType();
            if (data != null) {
                if (dataType == null) {
                    // 按对象实例的类型输出；
                    gen.writeObjectField("data", data);
                } else {
                    // 按指定类型输出；
                    writeDataField(data, dataType, responseObject.isOutputDataType(), gen, mapper);
                }
            }

            gen.writeEndObject();
        } catch (IOException e) {
            throw new RuntimeIOException(e.getMessage(), e);
        }

    }

    private void writeDataField(Object data,
            Class<?> dataType, boolean outputDataType, JsonGenerator gen, ObjectMapper mapper) throws IOException {
        // 按指定类型输出；
        writeField("data", data, dataType, gen, mapper);

        // 输出类型；
        if (outputDataType) {
            gen.writeStringField("dataType", dataType.getName());
        }
    }

    private void writeField(String fieldName, Object fieldData, Class<?> dataType, JsonGenerator gen,
            ObjectMapper mapper) throws IOException {
        // 按指定类型输出；
        gen.writeFieldName(fieldName);
        mapper.writerFor(dataType).writeValue(gen, fieldData);
    }

}
